﻿Imports System.ComponentModel
Imports System.Threading
Imports Ionic.Zip
Imports System.IO
Imports System.Reflection

Class MainWindow
    Implements INotifyPropertyChanged

#Region "Properties"
    Private _LiquidRomFile As String
    Public Property LiquidRomFile As String
        Get
            Return _LiquidRomFile
        End Get
        Set(value As String)
            If value <> _LiquidRomFile Then
                _LiquidRomFile = value
                OnPropertyChanged("LiquidRomFile")
                OnPropertyChanged("IsReady")
            End If
        End Set
    End Property

    Private _N1RomFile As String
    Public Property N1RomFile As String
        Get
            Return _N1RomFile
        End Get
        Set(value As String)
            If value <> _N1RomFile Then
                _N1RomFile = value
                OnPropertyChanged("N1RomFile")
                OnPropertyChanged("IsReady")
            End If
        End Set
    End Property

    Private _WorkingDirectory As String
    Public Property WorkingDirectory As String
        Get
            Return _WorkingDirectory
        End Get
        Set(value As String)
            If value <> _WorkingDirectory Then
                _WorkingDirectory = value
                OnPropertyChanged("WorkingDirectory")
            End If
        End Set
    End Property

    Private _IsDeleteApps As Boolean
    Public Property IsDeleteApps As Boolean
        Get
            Return _IsDeleteApps
        End Get
        Set(value As Boolean)
            If value <> _IsDeleteApps Then
                _IsDeleteApps = value
                OnPropertyChanged("IsDeleteApps")
            End If
        End Set
    End Property

    Private _IsSignPackage As Boolean
    Public Property IsSignPackage As Boolean
        Get
            Return _IsSignPackage
        End Get
        Set(value As Boolean)
            If value <> _IsSignPackage Then
                _IsSignPackage = value
                OnPropertyChanged("IsSignPackage")
            End If
        End Set
    End Property

    Public Property ExecutableDirectory As String

    Private _OutputFile As String
    Public Property OutputFile As String
        Get
            Return _OutputFile
        End Get
        Set(value As String)
            If value <> _OutputFile Then
                _OutputFile = value
                OnPropertyChanged("OutputFile")
                OnPropertyChanged("IsReady")
            End If
        End Set
    End Property

    Private _IsIdle As Boolean
    Public Property IsIdle As Boolean
        Get
            Return _IsIdle
        End Get
        Set(value As Boolean)
            If value <> _IsIdle Then
                _IsIdle = value
                OnPropertyChanged("IsIdle")
            End If
        End Set
    End Property

    Private _IsReady As Boolean
    Public ReadOnly Property IsReady As Boolean
        Get
            Return String.IsNullOrWhiteSpace(OutputFile) = False AndAlso
                String.IsNullOrWhiteSpace(N1RomFile) = False AndAlso
                String.IsNullOrWhiteSpace(LiquidRomFile) = False AndAlso
                OutputFile <> N1RomFile AndAlso
                OutputFile <> LiquidRomFile AndAlso
                N1RomFile <> LiquidRomFile
        End Get
    End Property

    Public Property ProgressWindow As ProgressWindow

#End Region

#Region "Methods"
    Public Sub New()
        IsIdle = True

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        WorkingDirectory = Path.GetTempPath & "com.mastert.autolimpot"

        Dim l = Assembly.GetExecutingAssembly().Location
        ExecutableDirectory = l.Substring(0, l.LastIndexOf("\"))
    End Sub


    Private Sub BuildRom(sender As Object)
        Try
            'Check for Java
            ProgressWindow.StartNextStep()
            Dim javapath As String = ""
            Try
                javapath = UtilityClass.GetJavaInstallationPath & "\bin\java.exe"
            Catch ex As Exception
                javapath = String.Empty
            End Try

            If String.IsNullOrWhiteSpace(javapath) OrElse Not File.Exists(javapath) Then
                Dim resul = MessageBox.Show("I was not able to find Java automatically." & vbCrLf & vbCrLf &
                                            "This may be because you don't have java installed or because of a bug in the detection system. If you're SURE you have Java installed, click ""Yes"" and navigate manually to java.exe" & vbCrLf &
                                            "If you do NOT have Java installed, click ""No"", close the program, install Java (www.java.com) and try again." & vbCrLf & vbCrLf &
                                            "Search manually for java.exe?", "Java not found", MessageBoxButton.YesNo, MessageBoxImage.Question)
                If resul = MessageBoxResult.Yes Then
                    javapath = UtilityClass.GetJavaManually
                End If

                If Not File.Exists(javapath) Then
                    ProgressWindow.CurrentStepFailed("Java is not installed on this machine. Please install the Java Runtime Enviroment (www.java.com) and try again")
                    Throw New ConversionUnfinishedException
                End If
            End If
            ProgressWindow.FinishCurrentStep()


            'Check for write access to working directory & cleanup
            ProgressWindow.StartNextStep()
            Try
                If Directory.Exists(WorkingDirectory) Then
                    Directory.Delete(WorkingDirectory, True)
                End If
                Directory.CreateDirectory(WorkingDirectory)
            Catch ex As Exception
                ProgressWindow.CurrentStepFailed("I cannot get write access to the TEMP folder. Make sure you have persmission to write to the TEMP folder, that no other process is locking it and that you have enough free disk space", ex.Message)
                Throw New ConversionUnfinishedException
            End Try

            ProgressWindow.FinishCurrentStep()


            'Extracting N1 ROM
            ProgressWindow.StartNextStep()
            Try
                Using n1zip As ZipFile = ZipFile.Read(N1RomFile)
                    n1zip.ExtractAll(WorkingDirectory & "\n1rom")
                End Using
            Catch ex As Exception
                ProgressWindow.CurrentStepFailed("Error while extracting N1 Rom. The file may be damaged, or another disk related error might have appened.", ex.Message)
                Throw New ConversionUnfinishedException
            End Try
            ProgressWindow.FinishCurrentStep()


            'Extracting Liquid ROM
            ProgressWindow.StartNextStep()
            Try
                Using n1zip As ZipFile = ZipFile.Read(LiquidRomFile)
                    n1zip.ExtractAll(WorkingDirectory & "\LiquidRom")
                End Using
            Catch ex As Exception
                ProgressWindow.CurrentStepFailed("Error while extracting Liquid Rom. The file may be damaged, or another disk related error might have appened.", ex.Message)
                Throw New ConversionUnfinishedException
            End Try
            ProgressWindow.FinishCurrentStep()


            'Installing apktool & signapk
            ProgressWindow.StartNextStep()
            Try
                File.Copy(ExecutableDirectory & "\apktool.jar", WorkingDirectory & "\apktool.jar")
                File.Copy(ExecutableDirectory & "\SignApk\signapk.jar", WorkingDirectory & "\signapk.jar")
                File.Copy(ExecutableDirectory & "\SignApk\testkey.pk8", WorkingDirectory & "\testkey.pk8")
                File.Copy(ExecutableDirectory & "\SignApk\testkey.x509.pem", WorkingDirectory & "\testkey.x509.pem")
            Catch ex As Exception
                ProgressWindow.CurrentStepFailed("Error while copying tools to working directory. May be related to write permissions, missing tools in application folder or not enough disk space", ex.Message)
                Throw New ConversionUnfinishedException
            End Try
            ProgressWindow.FinishCurrentStep()


            'Running APKtool
            'Backsmaling Liquid services.jar
            Dim psi As ProcessStartInfo
            Dim theButcher As Process
            Dim myOutput As StreamReader

            ProgressWindow.StartNextStep()
            Try
                psi = New ProcessStartInfo(javapath)
                psi.WorkingDirectory = WorkingDirectory & "\LiquidRom\system\framework"
                psi.RedirectStandardOutput = True
                psi.WindowStyle = ProcessWindowStyle.Hidden
                psi.UseShellExecute = False
                psi.CreateNoWindow = True
                psi.Arguments = "-jar " & """" & WorkingDirectory & "\apktool.jar"" if " & """" & WorkingDirectory & "\LiquidRom\system\framework\framework-res.apk"""
                theButcher = Process.Start(psi)
                myOutput = theButcher.StandardOutput
                theButcher.WaitForExit()
                psi.Arguments = "-jar " & """" & WorkingDirectory & "\apktool.jar"" d " & """" & WorkingDirectory & "\LiquidRom\system\framework\services.jar"""
                theButcher = Process.Start(psi)
                myOutput = theButcher.StandardOutput
                theButcher.WaitForExit()
            Catch ex As Exception
                ProgressWindow.CurrentStepFailed("Error while decompiling LiquidRom's services.jar", ex.Message)
                Throw New ConversionUnfinishedException
            End Try
            ProgressWindow.FinishCurrentStep()



            'Backsmaling N1 services.jar
            ProgressWindow.StartNextStep()
            Try
                psi = New ProcessStartInfo(javapath)
                psi.WorkingDirectory = WorkingDirectory & "\n1rom\system\framework"
                psi.RedirectStandardOutput = True
                psi.WindowStyle = ProcessWindowStyle.Hidden
                psi.UseShellExecute = False
                psi.CreateNoWindow = True
                psi.Arguments = "-jar " & """" & WorkingDirectory & "\apktool.jar"" if " & """" & WorkingDirectory & "\n1rom\system\framework\framework-res.apk"""
                theButcher = Process.Start(psi)
                myOutput = theButcher.StandardOutput
                theButcher.WaitForExit()
                psi.Arguments = "-jar " & """" & WorkingDirectory & "\apktool.jar"" d " & """" & WorkingDirectory & "\n1rom\system\framework\services.jar"""
                theButcher = Process.Start(psi)
                myOutput = theButcher.StandardOutput
                theButcher.WaitForExit()
            Catch ex As Exception
                ProgressWindow.CurrentStepFailed("Error while decompiling N1's services.jar", ex.Message)
                Throw New ConversionUnfinishedException
            End Try
            ProgressWindow.FinishCurrentStep()


            'Patching Proxymity
            ProgressWindow.StartNextStep()
            Try
                Dim text As String
                Using r As New StreamReader(WorkingDirectory & "\n1rom\system\framework\services.jar.out\smali\com\android\server\PowerManagerService$13.smali")
                    text = r.ReadToEnd
                    r.Close()
                End Using

                text = text.Replace("3e8", "0")

                Using w As New StreamWriter(WorkingDirectory & "\n1rom\system\framework\services.jar.out\smali\com\android\server\PowerManagerService$13.smali", False)
                    w.Write(text)
                    w.Close()
                End Using
            Catch ex As Exception
                ProgressWindow.CurrentStepFailed("Error while patching proximity sensor file", ex.Message)
                Throw New ConversionUnfinishedException
            End Try
            ProgressWindow.FinishCurrentStep()


            'Patching LEDs
            ProgressWindow.StartNextStep()
            Try
                File.Copy(WorkingDirectory & "\LiquidRom\system\framework\services.jar.out\smali\com\android\server\NotificationManagerService.smali",
                      WorkingDirectory & "\n1rom\system\framework\services.jar.out\smali\com\android\server\NotificationManagerService.smali", True)
            Catch ex As Exception
                ProgressWindow.CurrentStepFailed("Error while patching LED notification file", ex.Message)
                Throw New ConversionUnfinishedException
            End Try
            ProgressWindow.FinishCurrentStep()

            'Patching adb link
            ProgressWindow.StartNextStep()
            Try
                For Each f In Directory.GetFiles(WorkingDirectory & "\n1rom\system\framework\services.jar.out\smali\com\android\server\usb")
                    If f.Split(CChar("\")).Last.StartsWith("UsbService") Then
                        File.Delete(f)
                    End If
                Next
                For Each f In Directory.GetFiles(WorkingDirectory & "\LiquidRom\system\framework\services.jar.out\smali\com\android\server\usb")
                    If f.Split(CChar("\")).Last.StartsWith("UsbService") Then
                        File.Copy(f, f.Replace("\LiquidRom\", "\n1rom\"))
                    End If
                Next
            Catch ex As Exception
                ProgressWindow.CurrentStepFailed("Error while patching USB debugging link", ex.Message)
                Throw New ConversionUnfinishedException
            End Try
            ProgressWindow.FinishCurrentStep()

            'Rebuilding Services.jar
            ProgressWindow.StartNextStep()
            Try
                File.Delete(WorkingDirectory & "\n1rom\system\framework\services.jar")

                psi = New ProcessStartInfo(javapath)
                psi.WorkingDirectory = WorkingDirectory & "\n1rom\system\framework"
                psi.RedirectStandardOutput = True
                psi.WindowStyle = ProcessWindowStyle.Hidden
                psi.UseShellExecute = False
                psi.CreateNoWindow = True
                psi.Arguments = "-jar " & """" & WorkingDirectory & "\apktool.jar"" b """ & WorkingDirectory & "\n1rom\system\framework\services.jar.out"" """ & WorkingDirectory & "\n1rom\system\framework\services.jar"""
                theButcher = Process.Start(psi)
                myOutput = theButcher.StandardOutput
                theButcher.WaitForExit()
                Dim out = myOutput.ReadToEnd
            Catch ex As Exception
                ProgressWindow.CurrentStepFailed("Error while Rebuilding service.jar", ex.Message)
                Throw New ConversionUnfinishedException
            End Try
            ProgressWindow.FinishCurrentStep()

            'Cleaning up services folder
            ProgressWindow.StartNextStep()
            Try
                Directory.Delete(WorkingDirectory & "\LiquidRom\system\framework\services.jar.out", True)

                'Replacing services and apps
                For Each f In Directory.GetFiles(WorkingDirectory & "\LiquidRom\system\framework")
                    File.Delete(f)
                Next
                For Each f In Directory.GetFiles(WorkingDirectory & "\LiquidRom\system\app")
                    File.Delete(f)
                Next

                For Each f In Directory.GetFiles(WorkingDirectory & "\n1rom\system\framework")
                    File.Copy(f, f.Replace("n1rom", "LiquidRom"))
                Next
                For Each f In Directory.GetFiles(WorkingDirectory & "\n1rom\system\app")
                    File.Copy(f, f.Replace("n1rom", "LiquidRom"))
                Next

                'Updating Libs and bins
                Dim dirs = New String() {WorkingDirectory & "\n1rom\system\lib", WorkingDirectory & "\n1rom\system\bin", WorkingDirectory & "\n1rom\system\xbin", WorkingDirectory & "\n1rom\system\etc"}
                For Each d In dirs
                    For Each f In Directory.GetFiles(d)
                        If Not File.Exists(f.Replace("n1rom", "LiquidRom")) Then
                            File.Copy(f, f.Replace("n1rom", "LiquidRom"))
                        End If
                    Next
                Next
            Catch ex As Exception
                ProgressWindow.CurrentStepFailed("Error while replacing apps/libs.", ex.Message)
                Throw New ConversionUnfinishedException
            End Try
            ProgressWindow.FinishCurrentStep()


            'Deleting useless apps
            If IsDeleteApps Then
                ProgressWindow.StartNextStep()
                Try
                    Dim files = New String() {WorkingDirectory & "\LiquidRom\system\app\Torch.apk", WorkingDirectory & "\LiquidRom\system\app\FM.apk"}
                    For Each f In files
                        File.Delete(f)
                    Next
                Catch ex As Exception
                    ProgressWindow.CurrentStepFailed("Error while deleting apps", ex.Message)
                    Throw New ConversionUnfinishedException
                End Try
                ProgressWindow.FinishCurrentStep()
            Else
                ProgressWindow.SkipNextStep()
            End If


            'Patching build.prop and updater-script
            ProgressWindow.StartNextStep()
            Try
                'reading version numbers
                Dim N1version As String = ""
                Using r As New StreamReader(WorkingDirectory & "\n1rom\system\build.prop")
                    While Not r.EndOfStream
                        Dim line = r.ReadLine
                        If line.StartsWith("ro.build.version.incremental") Then
                            N1version = line.Split(CChar("="))(1)
                        End If
                    End While
                    r.Close()
                End Using

                Dim Liquidversion As String = ""
                Using r As New StreamReader(WorkingDirectory & "\LiquidRom\system\build.prop")
                    While Not r.EndOfStream
                        Dim line = r.ReadLine
                        If line.StartsWith("ro.build.version.incremental") Then
                            Liquidversion = line.Split(CChar("="))(1)
                        End If
                    End While
                    r.Close()
                End Using

                Dim text As String
                Using r As New StreamReader(WorkingDirectory & "\LiquidRom\system\build.prop")
                    text = r.ReadToEnd
                    r.Close()
                End Using

                text = text.Replace(Liquidversion, N1version)

                Using w As New StreamWriter(WorkingDirectory & "\LiquidRom\system\build.prop", False)
                    w.Write(text)
                    w.Close()
                End Using


                'Patching updater script
                Dim packagerline As String = ""
                Dim versionline As String = ""
                Using r As New StreamReader(WorkingDirectory & "\LiquidRom\META-INF\com\google\android\updater-script")
                    While Not r.EndOfStream
                        Dim line = r.ReadLine
                        If line.Contains("PACKAGER:") Then
                            packagerline = line
                            Exit While
                        End If
                        If line.Contains("M I U I - v") Then
                            versionline = line
                        End If
                    End While
                    r.Close()
                End Using

                If Not String.IsNullOrWhiteSpace(packagerline) OrElse Not String.IsNullOrWhiteSpace(versionline) Then
                    Using r As New StreamReader(WorkingDirectory & "\LiquidRom\META-INF\com\google\android\updater-script")
                        text = r.ReadToEnd
                        r.Close()
                    End Using

                    text = text.Replace(packagerline, "ui_print("" DEVICE: Liquid       PACKAGER: Auto-LiMPoT"");")
                    text = text.Replace(versionline, "ui_print(""          M I U I - v " & N1version & """);")

                    Using w As New StreamWriter(WorkingDirectory & "\LiquidRom\META-INF\com\google\android\updater-script", False)
                        w.Write(text)
                        w.Close()
                    End Using
                End If
                
            Catch ex As Exception
                ProgressWindow.CurrentStepFailed("Error while updating build.prop", ex.Message)
                Throw New ConversionUnfinishedException
            End Try
            ProgressWindow.FinishCurrentStep()

            'Building ROM zip
            ProgressWindow.StartNextStep()
            Try
                Using zip As ZipFile = New ZipFile
                    zip.AddDirectory(WorkingDirectory & "\LiquidRom")
                    zip.Save(WorkingDirectory & "\unsigned.zip")
                End Using
            Catch ex As Exception
                ProgressWindow.CurrentStepFailed("Error while building the new ROM zip file. May be caused by missing write permissions or not enough free space on disk", ex.Message)
                Throw New ConversionUnfinishedException
            End Try
            ProgressWindow.FinishCurrentStep()


            'Signing ROM
            If IsSignPackage Then
                ProgressWindow.StartNextStep()
                Try
                    psi = New ProcessStartInfo(javapath)
                    psi.WorkingDirectory = WorkingDirectory
                    psi.RedirectStandardOutput = True
                    psi.WindowStyle = ProcessWindowStyle.Hidden
                    psi.UseShellExecute = False
                    psi.CreateNoWindow = True
                    psi.Arguments = "-jar signapk.jar testkey.x509.pem testkey.pk8 unsigned.zip " & """" & OutputFile & """"
                    theButcher = Process.Start(psi)
                    myOutput = theButcher.StandardOutput
                    theButcher.WaitForExit()
                    ProgressWindow.FinishCurrentStep()
                Catch ex As Exception
                    ProgressWindow.CurrentStepFailed("Error while signing ROM file. May be caused by missing write permissions or not enough free space on disk", ex.Message)
                    Throw New ConversionUnfinishedException
                End Try

            Else
                ProgressWindow.SkipNextStep()
                Try
                    If File.Exists(OutputFile) Then
                        File.Delete(OutputFile)
                    End If
                    File.Move(WorkingDirectory & "\unsigned.zip", OutputFile)
                Catch ex As Exception
                    ProgressWindow.CurrentStepFailed("Error while writing final ROM file to disk. May be caused by missing write permissions or not enough free space on disk", ex.Message)
                    Throw New ConversionUnfinishedException
                End Try

            End If

            ProgressWindow.Success()

            IsIdle = True


        Catch ex As ConversionUnfinishedException
            IsIdle = True
            Return
        End Try
    End Sub
#End Region

#Region "Event Handlers"
    Private Sub ButtonClick_SelectLiquidRom(sender As System.Object, e As System.Windows.RoutedEventArgs)
        Dim dialog As New Windows.Forms.OpenFileDialog
        Dim result = dialog.ShowDialog
        If result = Forms.DialogResult.OK OrElse result = Forms.DialogResult.Yes Then
            LiquidRomFile = dialog.FileName
        End If
        e.Handled = True
    End Sub

    Private Sub ButtonClick_SelectN1Rom(sender As System.Object, e As System.Windows.RoutedEventArgs)
        Dim dialog As New Windows.Forms.OpenFileDialog
        Dim result = dialog.ShowDialog
        If result = Forms.DialogResult.OK OrElse result = Forms.DialogResult.Yes Then
            N1RomFile = dialog.FileName
        End If
        e.Handled = True
    End Sub

    Private Sub ButtonClick_SelectOutputPath(sender As System.Object, e As System.Windows.RoutedEventArgs)
        Dim dialog As New Windows.Forms.SaveFileDialog
        Dim result = dialog.ShowDialog
        If result = Forms.DialogResult.OK OrElse result = Forms.DialogResult.Yes Then
            OutputFile = dialog.FileName
        End If
        e.Handled = True
    End Sub

    Private Sub ButtonClick_Exit(sender As System.Object, e As System.Windows.RoutedEventArgs)
        Me.Close()
    End Sub

    Private Sub ButtonClick_BuildROM(sender As System.Object, e As System.Windows.RoutedEventArgs)
        IsIdle = False
        ProgressWindow = New ProgressWindow

        Dim doWork As WaitCallback = New WaitCallback(AddressOf BuildRom)
        ThreadPool.QueueUserWorkItem(doWork, sender)

        ProgressWindow.ShowDialog()
    End Sub

    Private Sub ButtonAbout_Click(sender As System.Object, e As System.Windows.RoutedEventArgs)
        Dim w As New AboutWindow
        w.ShowDialog()
    End Sub
#End Region


    Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
    Private Overloads Sub OnPropertyChanged(name As String)
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(name))
    End Sub


 
End Class